package com.tansun.easycare.rule.front.service.impl;

import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.tansun.easycare.rule.datasource.dao.RuleDatasheetColumnDao;
import com.tansun.easycare.rule.datasource.dao.RuleDatasheetDao;
import com.tansun.easycare.rule.datasource.entity.RuleDatasheet;
import com.tansun.easycare.rule.datasource.entity.RuleDatasheetColumn;
import com.tansun.easycare.rule.front.dao.RuleDatasourceDao;
import com.tansun.easycare.rule.front.dao.RuleEnterpointParamDao;
import com.tansun.easycare.rule.front.entity.RuleDatasource;
import com.tansun.easycare.rule.front.service.FrontService;
import com.tansun.easycare.rule.front.util.JsonUtils;

@Service
public class FrontServiceImpl implements FrontService {

	private Logger log = LoggerFactory.getLogger(FrontServiceImpl.class);
	
	@Autowired
	private RuleDatasourceDao dsDao;
	@Autowired
	private RuleDatasheetDao sheetDao;
	@Autowired
	private RuleDatasheetColumnDao colDao;
	@Autowired
	private RuleEnterpointParamDao paramDao;

	@SuppressWarnings("unchecked")
	public String processData(String projectCode,String enterPoint,String input) throws Exception{
		
		//解析报文
		Map<String,Object> inputMap = JsonUtils.parse(input, Map.class);
		//获取数据源列表
		List<RuleDatasource> dsList = dsDao.findList(new RuleDatasource());
		//处理关系型数据源
		processSQL(projectCode,enterPoint,inputMap,dsList);
		//处理HBase数据源
		processHBase(projectCode, enterPoint, inputMap, dsList);
		//最后.重新组装报文
		return JsonUtils.assemble(inputMap);
	}

	private void processHBase(String projectCode,String enterPoint,Map<String, Object> inputMap,
			List<RuleDatasource> dsList) throws Exception{
		//获取请求参数配置信息
//		RuleEnterpointParam param = new RuleEnterpointParam();
//		param.setProjectCode(projectCode);
//		param.setEnterCode(enterPoint);
//		List<RuleEnterpointParam> paramList = paramDao.findList(param);
//		//不存在配置信息，不做处理
//		if(param==null||paramList.size()<=0){
//			return;
//		}
//		//根据每个参数的数据源信息配置，获取外部数据
//		for(RuleEnterpointParam e:paramList){
//			RuleDatasource dataSource = findByDatasourceId(dsList,e.getDatasourceId());
//			if("HBase".equals(dataSource.getDsType())){
//				String[] ary = e.getDsRowKey().split("\\.");
//				String dataset = ary[0];
//				String datamodel = ary[1];
//				Map datasetMap = (Map) inputMap.get(dataset);
//				if(datasetMap==null||datasetMap.get(datamodel)==null){
//					log.info("入参不存在:"+e.getDsRowKey());
//					continue;
//				}
//				String rowKey = datasetMap.get(datamodel).toString();
//				//从hbase获取数据
//				Connection connection = HbaseUtil.getConnection(dataSource);
//				String val = HbaseUtil.findColByRowKey(connection, e.getDsTable(), e.getDsCol(), rowKey);
//				if(val==null){
//					continue;
//				}
//				//将获取到的数据赋值到请求参数中
//				ary = e.getDsDataparam().split("\\.");
//				dataset = ary[0];
//				datamodel = ary[1];
//				if(inputMap.get(dataset)==null){
//					inputMap.put(dataset, new HashMap());
//				}
//				Map map = (Map) inputMap.get(dataset);
//				map.put(datamodel, val);
//				
//			}
//		}
				
	}

	private void processSQL(String projectCode, String enterPoint, Map<String, Object> inputMap,
			List<RuleDatasource> dsList) throws Exception {
		//查找入口点对应的数据表配置
		RuleDatasheet sheet = new RuleDatasheet();
		sheet.setProjectCode(projectCode);
		sheet.setEnterCode(enterPoint);
		List<RuleDatasheet> sheetList = sheetDao.findList(sheet);
		//不存配置信息,不做进一步处理
		if(sheetList==null||sheetList.size()==0){
			return ;
		}
		//遍历配置的数据库,获取表数据
		for(RuleDatasheet e:sheetList){
			//查询表对应的字段配置信息
			RuleDatasheetColumn col = new RuleDatasheetColumn();
			col.setDatasheetId(e.getId());
			List<RuleDatasheetColumn> colList = colDao.findList(col);
			List<String> params = new ArrayList<String>();
			String sql = getSql(e,colList,inputMap,params);
			RuleDatasource datasource = this.findByDatasourceId(dsList, e.getDatasourceId());
			queryData(datasource,sql,params,colList,inputMap);
		}
	}


	private void queryData(RuleDatasource datasource, String sql, List<String> params,
			List<RuleDatasheetColumn> colList, Map<String, Object> inputMap) throws Exception {
		if("Oracle".equals(datasource.getDsType())){
			Class.forName("oracle.jdbc.driver.OracleDriver");
		}else if("MySQL".equals(datasource.getDsType())){
			Class.forName("com.mysql.jdbc.Driver");
		}else{
			log.warn("不支持的数据库类型:"+datasource.getDsType());
			return ;
		}
		try(java.sql.Connection connection = DriverManager.getConnection(datasource.getDsUrl(), datasource.getDsUsername(), datasource.getDsPwd());){
			PreparedStatement stmt = connection.prepareStatement(sql);
			for(int i=0;i<params.size();i++){
				stmt.setString(1+i, params.get(i));
			}
			ResultSet rs = stmt.executeQuery();
			if(rs.next()){
				for(RuleDatasheetColumn col:colList){
					//取出有映射的列值，再赋到输入参数中
					if(col.getMapingField()!=null&&!"".equals(col.getMapingField())){
						String val = rs.getString(col.getName());
						String[] ary = col.getMapingField().split("\\.");
						String dataset = ary[0];
						String var = ary[1];
						if(inputMap.get(dataset)==null){
							inputMap.put(dataset, new HashMap());
						}
						Map map = (Map) inputMap.get(dataset);
						map.put(var, val);
					}
				}
			}
		}
		
	}


	private String getSql(RuleDatasheet table, List<RuleDatasheetColumn> colList, Map<String, Object> inputMap, List<String> params) {
		StringBuilder select = new StringBuilder("select ");
		StringBuilder where = new StringBuilder(" where ");
		for(RuleDatasheetColumn col:colList){
			//有做映射的字段才加入到查询中
			if(col.getMapingField()!=null&&!"".equals(col.getMapingField())){
				select.append(col.getName()).append(",");
			}
			
			//有条件过滤的字段才加入到查询中
			if(col.getDataField()!=null&&!"".equals(col.getDataField())){
				String[] ary = col.getDataField().split("\\.");
				String dataset = ary[0];
				String var = ary[1];
				if(inputMap.get(dataset)!=null && ((Map)inputMap.get(dataset)).get(var)!=null){
					where.append(col.getName()).append(" = ? ").append("and");
					params.add(((Map)inputMap.get(dataset)).get(var).toString());
				}
			}
			
		}
		select.append("1 from ").append(table.getName()).append(where).append("1=1");
		return select.toString();
		
	}


	private RuleDatasource findByDatasourceId(List<RuleDatasource> dsList, String datasourceId) {
		for(RuleDatasource e:dsList){
			if(e.getId().equals(datasourceId)){
				return e;
			}
		}
		throw new RuntimeException("数据源信息不存在[id="+datasourceId+"]");
	}
}
